#include "n32g430.h"
#include "drv_pwm.h"

static  uint16_t TimerPeriod   = 0;

void DPM_PwmInit(void)
{
    // uint32_t ADTIMClockFrequency = 0;
    // RCC_ClocksType RCC_Clocks;
    //时钟开启
    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
    RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_TIM2);
    // RCC_Pclk1_Config(RCC_HCLK_DIV2); //32M Hz,默认; x2后为64M Hz
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);

    // RCC_Clocks_Frequencies_Value_Get(&RCC_Clocks);
    // if(RCC_Clocks.HclkFreq > RCC_Clocks.Pclk2Freq) 
    // {
    //     ADTIMClockFrequency = RCC_Clocks.Pclk2Freq * 2; 
    // }
    // else
    // {
    //     ADTIMClockFrequency = RCC_Clocks.Pclk2Freq;
    // }

    //引脚配置 PA1
    GPIO_InitType GPIO_InitStructure;
    GPIO_Structure_Initialize(&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Current = GPIO_DS_4MA;
    /* TIM_PWM CH2 pins init */
    GPIO_InitStructure.Pin        = GPIO_PIN_1;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF3_TIM2;
    GPIO_Peripheral_Initialize(GPIOA, &GPIO_InitStructure);

    //定时器配置
    // uint16_t TimerPrescaler = 0;
    uint16_t Channel2Pulse = 0;
   /* Compute the value to be set in AR register to generate signal frequency at 50 hz */
    // TimerPrescaler = 1000;
    TimerPeriod = (ADTIMClockFrequency / TimerPrescaler / PWM_FREQ) - 1;
    /* Compute CCDAT2 value to generate a duty cycle at 25%  for channel 2 */
    Channel2Pulse = (uint16_t)(((uint32_t)25 * (TimerPeriod - 1)) / 100);
    /* TIM Base Init, Period = TimerPeriod, Prescaler = 0 */
    TIM_TimeBaseInitType TIM_TimeBaseStructure;
    TIM_Base_Struct_Initialize(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.Period    = TimerPeriod;
    TIM_TimeBaseStructure.Prescaler = TimerPrescaler;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
    TIM_Base_Initialize(TIM_PWM, &TIM_TimeBaseStructure);  

    OCInitType TIM_OCInitStructure; 
    TIM_Output_Channel_Struct_Initialize(&TIM_OCInitStructure);
    /* Channel  2  Configuration in PWM mode */
    TIM_OCInitStructure.OcMode       = TIM_OCMODE_PWM2;
    TIM_OCInitStructure.OutputState  = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.OutputNState = TIM_OUTPUT_NSTATE_ENABLE;
    TIM_OCInitStructure.Pulse        = Channel2Pulse;
    TIM_OCInitStructure.OcPolarity   = TIM_OC_POLARITY_LOW;
    TIM_OCInitStructure.OcNPolarity  = TIM_OCN_POLARITY_LOW;
    TIM_OCInitStructure.OcIdleState  = TIM_OC_IDLE_STATE_SET;
    TIM_OCInitStructure.OcNIdleState = TIM_OCN_IDLE_STATE_RESET;
    TIM_Output_Channel2_Initialize(TIM_PWM, &TIM_OCInitStructure);

    TIM_On(TIM_PWM);
    TIM_PWM_Output_Enable(TIM_PWM);
}

void DPM_DutySet(float duty)
{
    uint16_t ch2_compare = (uint16_t)((duty * (TimerPeriod - 1)) / 100);;
    TIM_Compare2_D_Set(TIM_PWM, ch2_compare);
}


